﻿using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using System.Text;

namespace util_c_sharp
{
    internal class MqttConfig
    {
        private static IMqttClient? mqttClient = null;
        private static IMqttClientOptions? options = null;
        private static string ServerUrl = "182.61.51.85";
        private static int Port = 61613;
        private static string Password = "ruichi8888";
        private static string UserId = "admin";
        private static string Topic = "China/Hunan/Yiyang/Nanxian";
        private static bool Retained = false;
        /// <summary>       
        /// 服务质量        
        /// <para>0 - 至多一次</para>        
        /// <para>1 - 至少一次</para>        
        /// <para>2 - 刚好一次</para>        
        /// </summary>        
        private static int QualityOfServiceLevel = 0;

        internal void Work()
        {
            Console.WriteLine("开始启动mqtt");
            MqttFactory mqttFactory = new MqttFactory();
            mqttClient = mqttFactory.CreateMqttClient();
            var options = new MqttClientOptionsBuilder()   
                            .WithTcpServer(ServerUrl, Port)
                            .WithCredentials(UserId, Password)
                            .WithClientId("XMan")
                            .Build();

            mqttClient.ConnectAsync(options);


            mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnAppMessage);
            mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnConnected);
            mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnDisconnected);

        }

        private void OnAppMessage(MqttApplicationMessageReceivedEventArgs e)
        {
            string text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
            string Topic = e.ApplicationMessage.Topic; string QoS = e.ApplicationMessage.QualityOfServiceLevel.ToString();
            string Retained = e.ApplicationMessage.Retain.ToString();
            Console.WriteLine("MessageReceived >>Topic:" + Topic + "; QoS: " + QoS + "; Retained: " + Retained + ";");
            Console.WriteLine("MessageReceived >>Msg: " + text);
        }

        private void OnConnected(MqttClientConnectedEventArgs e)
        {
            // 订阅主题
            Subscribe();
        }

        private void OnDisconnected(MqttClientDisconnectedEventArgs e)
        {
        }

        private void Subscribe()
        {
            var topicFilterBulder = new MqttTopicFilter();
            topicFilterBulder.Topic = Topic;
            List<MqttTopicFilter> listTopic = new List<MqttTopicFilter>();
            listTopic.Add(topicFilterBulder);
            mqttClient.SubscribeAsync(listTopic.ToArray());
        }

        /// <summary>       
        /// /// 发布        
        /// <paramref name="QoS"/>        
        /// <para>0 - 最多一次</para>        
        /// <para>1 - 至少一次</para>        
        /// <para>2 - 仅一次</para>        
        /// </summary>       
        /// <param name="Topic">发布主题</param>        
        /// <param name="Message">发布内容</param>        
        /// <returns></returns>        
        public static void Publish(string Topic, string Message)
        {
            try
            {
                if (mqttClient == null)
                    return;
                if (mqttClient.IsConnected == false)
                    mqttClient.ConnectAsync(options);
                if (mqttClient.IsConnected == false)
                {
                    Console.WriteLine("Publish >>Connected Failed! ");
                    return;
                }
                Console.WriteLine("Publish >>Topic: " + Topic + "; QoS: " + QualityOfServiceLevel + "; Retained: " + Retained + ";");
                Console.WriteLine("Publish >>Message: " + Message);
                MqttApplicationMessageBuilder mamb = new MqttApplicationMessageBuilder()
                    .WithTopic(Topic)
                    .WithPayload(Message).WithRetainFlag(Retained);
                if (QualityOfServiceLevel == 0)
                {
                    mamb = mamb.WithAtMostOnceQoS();
                }
                else if (QualityOfServiceLevel == 1)
                {
                    mamb = mamb.WithAtLeastOnceQoS();
                }
                else if (QualityOfServiceLevel == 2)
                {
                    mamb = mamb.WithExactlyOnceQoS();
                }
                mqttClient.PublishAsync(mamb.Build());
            }
            catch (Exception exp)
            {
                Console.WriteLine("Publish >>" + exp.Message);
            }
        }
    }
}
